using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
using AutoMapper;
using HuiLian.Common.Input;
using HuiLian.Common.Output;
using HuiLian.Model.Platform;
using HuiLian.Repository.Platform;
using HuiLian.Service.Platform.PipeHealth.Input;
//using HuiLian.Service.Platform.PipeHealth.Output;
using HuiLian.Common.Attributes;
using HuiLian.Common;
using Microsoft.AspNetCore.Mvc;
using Org.BouncyCastle.Crypto;
using HuiLian.Service.Platform.PipeHealth.Output;
using static FreeSql.Internal.GlobalFilter;
using System;
using HuiLian.Common.Helpers;

namespace HuiLian.Service.Platform.PipeHealth
{
    /// <summary>
    /// 管段健康服务
    /// </summary>
    public class PipeHealthService : IPipeHealthService
    {
        private readonly IMapper _mapper;
        private readonly IPipeHealthRepository _pipeHealthRepository;
        private readonly IPipeRepository _pipeRepository;
        private readonly IPipeTeZhengDataRepository _teZhengDataRepository;
        private readonly IModelParamRepository _modelParamRepository;

        public PipeHealthService(
            IMapper mapper, 
            IPipeHealthRepository pipeHealthRepository, 
            IPipeRepository pipeRepository,
            IPipeTeZhengDataRepository teZhengDataRepository,
            IModelParamRepository modelParamRepository)
        {
            _mapper = mapper;
            _pipeHealthRepository = pipeHealthRepository;
            _pipeRepository = pipeRepository;
            _teZhengDataRepository = teZhengDataRepository;
            _modelParamRepository = modelParamRepository;
        }

        /// <summary>
        /// 获取管段健康信息
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        public async Task<IResponseOutput> GetAsync(long id)
        {
            var result = await _pipeHealthRepository.GetAsync(id);
            return ResponseOutput.Ok(result);
        }

        /// <summary>
        /// 查询管段健康信息
        /// </summary>
        /// <param name="input">分页信息</param>
        /// <returns></returns>
        public async Task<IResponseOutput> PageAsync(PageInput<PipeHealthEntity> input)
        {
            //var key = input.Filter?.Label;

            var list = await _pipeHealthRepository.Select
            //.WhereDynamicFilter(input.GetDynamicFilter<DynamicFilterInfo>())
            //.WhereIf(key.NotNull(), a => a.Path.Contains(key) || a.Label.Contains(key))
            .Count(out var total)
            .OrderByDescending(true, c => c.Id)
            .Page(input.CurrentPage, input.PageSize)
            .ToListAsync();

            var data = new PageOutput<PipeHealthEntity>()
            {
                List = list,
                Total = total
            };

            return ResponseOutput.Ok(data);
        }

        /// <summary>
        /// 添加管段健康信息
        /// </summary>
        /// <param name="input">管段健康信息</param>
        /// <returns></returns>
        public async Task<IResponseOutput> AddAsync(PipeHealthAddInput input)
        {
            var entity = _mapper.Map<PipeHealthEntity>(input);
            var id = (await _pipeHealthRepository.InsertAsync(entity)).Id;

            return ResponseOutput.Result(id > 0);
        }

        /// <summary>
        /// 更新管段健康信息
        /// </summary>
        /// <param name="input">管段健康信息</param>
        /// <returns></returns>
        public async Task<IResponseOutput> UpdateAsync(PipeHealthUpdateInput input)
        {
            if (!(input?.Id > 0))
            {
                return ResponseOutput.NotOk();
            }

            var entity = await _pipeHealthRepository.GetAsync(input.Id);
            if (!(entity?.Id > 0))
            {
                return ResponseOutput.NotOk("数据不存在！");
            }

            _mapper.Map(input, entity);
            await _pipeHealthRepository.UpdateAsync(entity);
            return ResponseOutput.Ok();
        }

        /// <summary>
        /// 删除管段健康信息
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        public async Task<IResponseOutput> DeleteAsync(long id)
        {
            var result = false;
            if (id > 0)
            {
                result = (await _pipeHealthRepository.DeleteAsync(m => m.Id == id)) > 0;
            }

            return ResponseOutput.Result(result);
        }

        /// <summary>
        /// 软删除管段健康信息
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        public async Task<IResponseOutput> SoftDeleteAsync(long id)
        {
            var result = await _pipeHealthRepository.SoftDeleteAsync(id);
            return ResponseOutput.Result(result);
        }

        /// <summary>
        /// 批量软删除管段健康信息
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task<IResponseOutput> BatchSoftDeleteAsync(long[] ids)
        {
            var result = await _pipeHealthRepository.SoftDeleteAsync(ids);

            return ResponseOutput.Result(result);
        }

        /// <summary>
        /// 获取危险阈值
        /// </summary>
        /// <returns></returns>
        private async Task<double> GetWeiXianYuzhi()
        {
            double weiXianYuzhi = 0.9;
            var modelParam = await _modelParamRepository.Select.FirstAsync();
            if (modelParam != null)
            {
                weiXianYuzhi = modelParam.threshold;
            }
            return weiXianYuzhi;
        }

        /// <summary>
        /// 管线状态， 如果是全部，Filter.健康度为空
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<IResponseOutput> PipelineStatus(PageInput<PipelineStatusInput> input)
        {
            double weiXianYuzhi = await GetWeiXianYuzhi();

            var list = await _teZhengDataRepository.Select
            //.WhereDynamicFilter(input.GetDynamicFilter<DynamicFilterInfo>())
            .WhereIf(input.Filter != null && input.Filter.健康度.NotNull() && input.Filter.健康度 == "危险", a => a.健康度 > weiXianYuzhi && a.健康度 <= 1)
            .WhereIf(input.Filter != null && input.Filter.健康度.NotNull() && input.Filter.健康度 == "较差", a => a.健康度 > 0.75 && a.健康度 <= weiXianYuzhi)
            .WhereIf(input.Filter != null && input.Filter.健康度.NotNull() && input.Filter.健康度 == "一般", a => a.健康度 > 0.5 && a.健康度 <= 0.75)
            .WhereIf(input.Filter != null && input.Filter.健康度.NotNull() && input.Filter.健康度 == "健康", a => a.健康度 >= 0 && a.健康度 <= 0.5)
            .WhereIf(input.Filter != null && input.Filter.健康度.NotNull() && input.Filter.健康度 == "未知", a => a.健康度 >= -2 && a.健康度 <= -1)
            .Count(out var total)
            .OrderByDescending(true, c => c.健康度)
            .Page(input.CurrentPage, input.PageSize)
            .ToListAsync<PipelineStatusOutput>();

            List<PipelineStatusOutputView> result = new List<PipelineStatusOutputView>();
            foreach (var item in list)
            {
                PipelineStatusOutputView view = new PipelineStatusOutputView
                {
                    管段编号 = item.管段编号,
                    健康度 = PipeHelper.GetHealth(item.健康度, weiXianYuzhi),
                    所在道路 = item.所在道路
                };
                result.Add(view);
            }
            var data = new PageOutput<PipelineStatusOutputView>()
            {
                List = result,
                Total = total
            };

            return ResponseOutput.Ok(data);
        }

        /// <summary>
        /// 健康报告
        /// </summary>
        /// <param name="管段编号"></param>
        /// <returns></returns>
        public async Task<IResponseOutput> HealthReport(string 管段编号)
        {
            var pipe = await _pipeRepository.Select.Where(p => p.管段编号 == 管段编号).FirstAsync();
            if (pipe == null) return ResponseOutput.NotOk("管道不存在");

            HealthReportOutput result = new HealthReportOutput();
            result.PipeInfo = pipe;

            //获取危险下限阈值
            double weiXianYuzhi = await GetWeiXianYuzhi();

            var health = await _pipeHealthRepository.Select.Where(p => p.管段编号 == 管段编号).FirstAsync();
            result.healthIndicator = new HealthIndicator();
            if (health == null) result.healthIndicator.健康状态 = "未知";
            else result.healthIndicator.健康状态 = PipeHelper.GetHealth(health.健康度,weiXianYuzhi);

            result.healthIndicator.管长 = pipe.管长;
            result.healthIndicator.管径 = pipe.管径;
            result.healthIndicator.管材 = pipe.管材;
            result.healthIndicator.管龄 = DateTime.Now.Year - pipe.竣工接收时间.ToDateTime().Year;
            result.healthIndicator.竣工接收时间 = pipe.竣工接收时间;
            result.healthIndicator.普查时间 = pipe.普查时间;
            result.healthIndicator.管道类型 = pipe.类型;
            result.healthIndicator.破损次数 = pipe.维修次数;
            result.healthIndicator.维修次数 = pipe.维修次数;
            result.healthIndicator.计量区 = pipe.计量区;
            result.healthIndicator.接口种类 = pipe.连接类型;

            return ResponseOutput.Ok(result);
        }

    }
}
